/*
 * The RavenX Library
 * Copyright (c) 2008 by Solidus
 * 
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.It is provided "as is" without express 
 * or implied warranty.
 *
 */

#include "rx_misc.h"
#include "rx_mem.h"
#include <stdlib.h>
#include <string.h>

RX_SPACE_BEG


rx_uint64 rx_rand64()
{
		rx_uint64 res = rand();
		res ^= (rx_uint64)rand() << 15;
		res ^= (rx_uint64)rand() << 30;
		res ^= (rx_uint64)rand() << 45;
		res ^= (rx_uint64)rand() << 60;
		return res;

}

rx_uint32 rx_rand32()
{
		rx_uint32 res = rand();
		res ^= (rx_uint32)rand() << 15;
		res ^= (rx_uint32)rand() << 30;
		return res;
}





rx_int16 rx_flip_int16(rx_int16 val)
{
		return (rx_int16)rx_flip_uint16(val);
}

rx_uint16 rx_flip_uint16(rx_uint16 val)
{
		return (((val >> 8) & 0x00FF)| ((val << 8) & 0xFF00));
}


rx_int32 rx_flip_int32(rx_int32 val)
{
		return (rx_int32)rx_flip_uint32(val);
}

rx_uint32 rx_flip_uint32(rx_uint32 val)
{
		return (
				((val >> 24) &0x000000FF)|
				((val >> 8) & 0x0000FF00)|
				((val << 8) & 0x00FF0000)|
				((val << 24) & 0xFF000000)
				);

}

rx_int64 rx_flip_int64(rx_int64 val)
{
		return (rx_int64)rx_flip_uint64(val);

}

rx_uint64 rx_flip_uint64(rx_uint64 val)
{
		rx_uint32 lo,hi;
		rx_uint64 flo,fhi;

		hi = (rx_uint32)( val >> 32);
		lo = (rx_uint32)(val  & 0xFFFFFFFF00000000);

		fhi = (rx_uint64)(rx_flip_uint32(hi));
		flo = (rx_uint64)(rx_flip_uint32(lo));
		
		flo <<= 32;
		return flo|fhi;

}


rx_uint_n rx_hash_byte(const rx_byte *ptr, size_t n)
{
		rx_uint_n ret = 0;
		const rx_uint16 *p = (const rx_uint16*)ptr;
		size_t i;

		if(ptr == NULL || n == 0)return 0;

		
		n = (n * sizeof(rx_byte))/sizeof(rx_uint16);

		for(i = 0; i < n; ++i)
		{
				ret ^= (p[i] << (i & 0x0F));
		}

		return ret;
}

rx_uint_n rx_hash_str(const rx_char *str)
{
		size_t len;
		if(str == NULL)return 0;
		len = strlen(str);
		
		if(len == 0)return 0;

		return rx_hash_byte((const rx_byte*)str, (len + 1) * sizeof(rx_char));

}

rx_uint_n rx_hash_wstr(const rx_wchar *str)
{
		size_t len;
		if(str == NULL)return 0;
		len = wcslen(str);
		if(len == 0)return 0;
		return rx_hash_byte((const rx_byte*)str, (len + 1) * sizeof(rx_wchar));
}
















RX_SPACE_END

